#include "Embedding.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QEventLoop>
#include <QNetworkRequest>
#include <QDebug>
#include <QThread>

Embedding::Embedding() {

}

QVector<float> Embedding::getEmbedding(const QString& sentence, 
                                       const QString& embeddingAIUrl, 
                                       const QString& embeddingAIKey, 
                                       const QString& embeddingAIModel) {
    qDebug() << "正在获取句子的嵌入向量:" << sentence;
    int maxRetries = 3;
    int retryDelay = 10; 

    for (int i = 0; i < maxRetries; ++i) {
        qDebug() << "尝试次数:" << i + 1;
        QJsonObject response = sendRequest(sentence, embeddingAIUrl, embeddingAIKey, embeddingAIModel);
        if (response.isEmpty()) {
            qWarning() << "API请求失败，等待" << retryDelay << "毫秒后重试";
            QThread::msleep(retryDelay);
            continue;
        }
        
        QVector<float> embedding = parseResponse(response);
        if (embedding.isEmpty()) {
            qWarning() << "嵌入向量解析失败，等待" << retryDelay << "毫秒后重试";
            QThread::msleep(retryDelay);
            continue;
        }
        
        // 再次获取嵌入向量进行比较
        QJsonObject secondResponse = sendRequest(sentence, embeddingAIUrl, embeddingAIKey, embeddingAIModel);
        if (secondResponse.isEmpty()) {
            qWarning() << "第二次API请求失败，等待" << retryDelay << "毫秒后重试";
            QThread::msleep(retryDelay);
            continue;
        }
        
        QVector<float> secondEmbedding = parseResponse(secondResponse);
        if (secondEmbedding.isEmpty()) {
            qWarning() << "第二次嵌入向量解析失败，等待" << retryDelay << "毫秒后重试";
            QThread::msleep(retryDelay);
            continue;
        }
        
        if (embedding == secondEmbedding) {
            qDebug() << "成功获取一致的嵌入向量";
            return embedding;
        } else {
            qWarning() << "两次获取的嵌入向量不一致，尝试重新请求";
        }
    }
    qWarning() << "警告: 3次尝试后未能获取一致的嵌入向量,返回空向量";
    return QVector<float>();
}

QJsonObject Embedding::sendRequest(const QString& sentence, 
                                   const QString& embeddingAIUrl, 
                                   const QString& embeddingAIKey, 
                                   const QString& embeddingAIModel) {
    qDebug() << "发送API请求获取嵌入向量";
    QNetworkRequest request{QUrl(embeddingAIUrl)};
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("Authorization", QString("Bearer %1").arg(embeddingAIKey).toUtf8());

    QJsonObject json;
    json["input"] = sentence;
    json["model"] = embeddingAIModel;
    json["encoding_format"] = "float";

    QJsonDocument jsonDoc(json);
    QByteArray jsonData = jsonDoc.toJson();

    QNetworkReply *reply = manager.post(request, jsonData);

    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    if (reply->error() == QNetworkReply::NoError) {
        QByteArray responseData = reply->readAll();
        reply->deleteLater();

        return QJsonDocument::fromJson(responseData).object();
    } else {
        qWarning() << "API请求失败:" << reply->errorString();
        qWarning() << "Error details:" << reply->readAll();
        reply->deleteLater();
        return QJsonObject(); // 返回空对象表示请求失败
    }
}

QVector<float> Embedding::parseResponse(const QJsonObject& response) {
    qDebug() << "解析API响应";
    QVector<float> embedding;
    
    if (response.isEmpty()) {
        qWarning() << "API响应为空，无法解析";
        return embedding;
    }

    if (!response.contains("data") || !response["data"].isArray()) {
        qWarning() << "API响应格式错误，缺少data数组";
        return embedding;
    }

    QJsonArray dataArray = response["data"].toArray();
    if (dataArray.isEmpty() || !dataArray[0].isObject()) {
        qWarning() << "API响应格式错误，data数组为空或第一个元素不是对象";
        return embedding;
    }

    QJsonObject embeddingObject = dataArray[0].toObject();
    if (!embeddingObject.contains("embedding") || !embeddingObject["embedding"].isArray()) {
        qWarning() << "API响应格式错误，缺少embedding数组";
        return embedding;
    }

    QJsonArray embeddingArray = embeddingObject["embedding"].toArray();
    for (const QJsonValue& value : embeddingArray) {
        if (value.isDouble()) {
            embedding.append(value.toDouble());
        } else {
            qWarning() << "嵌入向量中包含非数值类型数据";
        }
    }
    
    qDebug() << "嵌入向量解析完成,维度:" << embedding.size();
    return embedding;
}
